﻿//-----------------------------------------------------------------------
// <copyright file="WpfExtensions.cs" company="xBrainLab">
//     Copyright (c) xBrainLab. All rights reserved.
// </copyright>
// <author>Sebastien Warin</author>
//-----------------------------------------------------------------------
namespace KinectTouchDevice
{
    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Media;

    public static class WpfExtensions
    {
        public static T GetParent<T>(this FrameworkElement source) where T : FrameworkElement
        {
            return TreeHelper.GetParent<T>(source);
        }

        public static T GetControlDecendantByName<T>(this DependencyObject reference, string name) where T : DependencyObject
        {
            return TreeHelper.GetControlDecendantByName<T>(reference, name);
        }

        public static T GetControlDecendant<T>(this DependencyObject reference) where T : DependencyObject
        {
            return TreeHelper.GetControlDecendant<T>(reference);
        }

        public static IEnumerable<T> GetControlsDecendant<T>(this DependencyObject reference) where T : DependencyObject
        {
            return TreeHelper.GetControlsDecendant<T>(reference);
        }
    }

    public partial class TreeHelper
    {
        public static T GetParent<T>(FrameworkElement source) where T : FrameworkElement
        {
            while (source != null && !(source is T))
            {
                source = source.Parent != null ? source.Parent as FrameworkElement : null;
            }
            return source != null ? source as T : default(T);
        }

        public static T GetControlDecendantByName<T>(DependencyObject reference, string name) where T : DependencyObject
        {
            var controls = GetControlsDecendant<T>(reference);
            if (controls != null)
            {
                foreach (var item in controls)
                {
                    FrameworkElement element = item as FrameworkElement;
                    if (element != null &&
                        element.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
                    {
                        return item;
                    }
                }
            }
            return default(T);
        }

        public static T GetControlDecendant<T>(DependencyObject reference) where T : DependencyObject
        {
            var controls = GetControlsDecendant<T>(reference);
            if (controls != null)
            {
                foreach (var item in controls)
                    return item;
            }
            return default(T);
        }

        public static IEnumerable<T> GetControlsDecendant<T>(DependencyObject reference) where T : DependencyObject
        {
            if (reference == null)
                yield break;
            int nbChildren = VisualTreeHelper.GetChildrenCount(reference);
            for (int index = 0; index < nbChildren; index++)
            {
                var child = VisualTreeHelper.GetChild(reference, index);
                T value = child as T;
                if (value != null)
                    yield return value;
                foreach (var childValue in GetControlsDecendant<T>(child))
                    yield return childValue;
            }
        }
    }
}
